Skip to content

Components: Add props for Toolspanel (isShownOnFirstRender)#78010

Open
im3dabasia wants to merge 5 commits intoWordPress:trunkfrom
im3dabasia:feat/render-optional-items-in-first-render
Open

Components: Add props for Toolspanel (isShownOnFirstRender)#78010
im3dabasia wants to merge 5 commits intoWordPress:trunkfrom
im3dabasia:feat/render-optional-items-in-first-render

Conversation

@im3dabasia
Copy link
Copy Markdown
Contributor

@im3dabasia im3dabasia commented May 6, 2026

What?

Focuses on: #41544 (comment), Conclusion comment for the discussion of the issue #41544 (comment)

Closes #41544

Adds new prop to the ToolsPanel component:

  • isShownOnFirstRender on ToolsPanelItem: allows optional items to be visible on first render without requiring a value
  • Updated gating logic for the onDeselect callback to run when the user toggles show/hide from the menu. This allows API consumers to track the shown/hidden states for their respective menu items.

Why?

Currently, optional ToolsPanelItem components are only rendered when they have a value or are toggled on by the user. There was no way to pre-show an optional item, or for consumers to know the current visibility state of items without reaching into internals.

How?

  • Added isShownOnFirstRender?: boolean to ToolsPanelItem props; used in generateMenuItems to set the initial menu state for optional items

Testing Instructions

  1. Render a ToolsPanel with an optional ToolsPanelItem and pass isShownOnFirstRender — the item should be visible on first paint

Use of AI Tools

GitHub Copilot

@im3dabasia im3dabasia self-assigned this May 6, 2026
@im3dabasia im3dabasia requested review from a team and ajitbohra as code owners May 6, 2026 11:07
@im3dabasia im3dabasia added [Type] Enhancement A suggestion for improvement. [Package] Components /packages/components [Feature] Design Tools Tools that impact the appearance of blocks both to expand the number of tools and improve the experi labels May 6, 2026
Copy link
Copy Markdown
Contributor

@aaronrobertshaw aaronrobertshaw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for putting the PR together 👍

I don’t think onVisibilityChange is the right direction here.

This adds a broad panel-level API for something that should remain item-level state. ToolsPanelItem already has onSelect and onDeselect, and those are the natural extension points for tracking whether a specific item has been shown or hidden.

The main issue is that the current callbacks are value-gated. That means an optional item can be shown, receive no value, and then be hidden without onDeselect firing. That should be extended or tweaked directly rather than adding a second panel-level visibility lifecycle.

My specific concerns with onVisibilityChange are:

• It exposes aggregate internal ToolsPanel menu state as public API.
• It reports visibility by label, which is not a stable identifier. Labels are user-facing, translatable, and subject to copy changes.
• It forces consumers to map parent-level label arrays back to individual controls.
• It is awkward for SlotFill injected items, where the panel owner and item owner may not be the same code.
• It can fire from registration changes, conditional rendering, value changes, and reset behaviour, not just an explicit user show/hide action.
• It does not replace onDeselect, because consumers still need item-level reset behaviour.
• The PR does not demonstrate a real consumer that proves this panel-level abstraction is necessary.

I think the better fix is to make onSelect and onDeselect fire on actual item menu selection transitions:

• item selected/shown from the menu → onSelect
• item deselected/hidden from the menu → onDeselect

That gives consumers the control needed to track/persist visibility at the item level, lets them use their own stable IDs, and avoids exposing the panel’s internal visibility bookkeeping as a new public API.

So I’d prefer we do not add onVisibilityChange and instead expand the existing ToolsPanelItem callbacks.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 7, 2026

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Unlinked Accounts

The following contributors have not linked their GitHub and WordPress.org accounts: @apeatling.

Contributors, please read how to link your accounts to ensure your work is properly credited in WordPress releases.

If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message.

Unlinked contributors: apeatling.

Co-authored-by: im3dabasia <im3dabasia1@git.wordpress.org>
Co-authored-by: aaronrobertshaw <aaronrobertshaw@git.wordpress.org>
Co-authored-by: ciampo <mciampini@git.wordpress.org>
Co-authored-by: mtias <matveb@git.wordpress.org>
Co-authored-by: annezazu <annezazu@git.wordpress.org>
Co-authored-by: markhowellsmead <markhowellsmead@git.wordpress.org>
Co-authored-by: bacoords <bacoords@git.wordpress.org>
Co-authored-by: fabiankaegy <fabiankaegy@git.wordpress.org>

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@aaronrobertshaw
Copy link
Copy Markdown
Contributor

I think the better fix is to make onSelect and onDeselect fire on actual item menu selection transitions:

One thing we might want to keep an eye on or add tests for is ensuring we aren't unnecessarily firing this onDeselect in terms of resetting values.

@im3dabasia
Copy link
Copy Markdown
Contributor Author

One thing we might want to keep an eye on or add tests for is ensuring we aren't unnecessarily firing this onDeselect in terms of resetting values.

Yes, exactly that. When setting aspect ratio to "Original", it programmatically hides the scale item, which now also triggers onDeselect on scale, causing onChange to fire a second time.

The isValueSet gate was preventing this, but removing it to fix the no-value case broke this scenario. The fix needs to distinguish user-initiated toggles from programmatic ones, happy to explore that if you can point me to the right place to thread that through context.

@aaronrobertshaw
Copy link
Copy Markdown
Contributor

This is something I'd need to spend some extra time digging into to give you an exact look here. Unfortunately, I'm a little preoccupied on other work at the moment before I'll be away for a couple of weeks.

My initial thought was to maybe pass the isValueSet through to the onDeselect however that would require all consumers to update their onDeselect callbacks.

Maybe we need onShow and onHide handlers. The onShow could be an alias to onSelect perhaps. The onHide gets called regardless of isValueSet whereas onDeselect is still value gated. None of this sounds great at the moment but hopefully it helps move the discussion forward.

Something else worth discussing could be changing the public API such that onDeselect is renamed to onReset.

Whatever we do we'll need to maintain backward compatibility as well as keep this visibility tracking and management all at the same level, the item level.

@im3dabasia im3dabasia force-pushed the feat/render-optional-items-in-first-render branch from 881b6a9 to 3aa09b3 Compare May 7, 2026 09:13
@im3dabasia
Copy link
Copy Markdown
Contributor Author

@aaronrobertshaw , Thanks for the quick responses.

What if we track whether a menu item was toggled by the user, and use that to gate onDeselect? This way it only fires on genuine user actions. Internal/programmatic state changes won't cause double calls.

It's a small change, maintains backward compatibility, and requires very few architectural modifications. Happy to explore further based on your feedback!

@im3dabasia im3dabasia changed the title Components: Add props for Toolspanel (isShownOnFirstRender and onVisibilityChange) Components: Add props for Toolspanel (isShownOnFirstRender) May 7, 2026
@im3dabasia im3dabasia requested a review from aaronrobertshaw May 7, 2026 09:23
@ciampo
Copy link
Copy Markdown
Contributor

ciampo commented May 7, 2026

I may not have much context, but could we migrate to a typical controlled/uncontroleld set of props to manage each ToolsPanel.Item "visibility" ? Ie. shown / defaultShown / onShownChange (name TBD)

Today's behaviour is uncontrolled, and could be kept the same (initial value set via defaultShown). A controlled approach would instead use shown and onShownChange.

Could that work?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Feature] Design Tools Tools that impact the appearance of blocks both to expand the number of tools and improve the experi [Package] Components /packages/components [Type] Enhancement A suggestion for improvement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ToolsPanel: Selected ToolsPanel menu options are not persistent

3 participants